#include "Plateau.h";
#include <fstream>
#include <sstream>

Plateau::Plateau()
{
	this->tailleX = 16;
	this->tailleY = 16;
}

Plateau::Plateau(int tailleX, int tailleY)
{
	this->tailleX = tailleX;
	this->tailleY = tailleY;
}

Plateau::Plateau(Plateau* Source)
{
	this->tailleX = Source->getTailleX();
	this->tailleY = Source->getTailleY();

	for(int y=0;y<tailleY;y++)
	{
		for(int x=0;x<tailleX;x++)
		{
			PlateauDeJeu[x][y]=new Piece(Source->getPiece(x,y));
		}
	}
}


Plateau::~Plateau(void)
{
}

Piece* Plateau::getPiece(int X,int Y)
{
	if(X < 16 && Y < 16 && X >= 0 && Y >= 0)
		return PlateauDeJeu[X][Y];
	else
		return 0;
}

void Plateau::setPiece(int X,int Y,Piece* LaPiece)
{
	if(X < 16 && Y < 16 && X >= 0 && Y >= 0)
		PlateauDeJeu[X][Y]=LaPiece;
	else
		cout << "Erreur de segmentation (segmentation fault)" << endl;
}

int Plateau::getTailleX()
{
	return this->tailleX;
}

int Plateau::getTailleY()
{
	return this->tailleY;
}

void Plateau::setTailleX(int tailleX)
{
	this->tailleX=tailleX;
}

void Plateau::setTailleY(int tailleY)
{
	this->tailleX=tailleY;
}

void Plateau::StringExplode(string str, string separator, vector<string>* results)
{
	int found;
	found = str.find_first_of(separator);
	while(found != string::npos)
	{
		if(found > 0)
		{
			results->push_back(str.substr(0,found));
		}
		str = str.substr(found+1);
		found = str.find_first_of(separator);
	}
	if(str.length() > 0)
	{
		results->push_back(str);
	}
}

int Plateau::StringToInt(string a)
{
	istringstream iss(a);
	int tmp;
	iss>>tmp;
	return tmp;
}

void Plateau::loadFile(string name)
{
	ifstream file( name );

	// compter le nombre de lignes
	int count = 0;

	string line;
	int y=0;
	int x=0;
	int Pas=0;

	vector<string> results;

	while ( getline( file, line ) )
	{
		results.clear();
		StringExplode(line, ",", &results);

		if (count < 5 )
		{
			switch(count)
			{
			case 1:
				setPiece(0,0, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::ANGLE, Piece::orient::EST));
				break;
			case 2:
				setPiece(15,0, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::ANGLE, Piece::orient::SUD));
				break;
			case 3:
				setPiece(0,15, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::ANGLE, Piece::orient::NORD));
				break;
			case 4:
				setPiece(15,15, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::ANGLE, Piece::orient::OUEST));
				break;
			}
		}else if(count < 19)
		{
			x++;
			setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::BORD, Piece::orient::SUD));
		}
		else if(count < 33)
		{
			y=(tailleY-1);
			setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::BORD, Piece::orient::NORD));
			x--;
		}
		else if(count < 47)
		{
			y--;
			x=0;
			setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::BORD, Piece::orient::EST));
		}
		else if(count < 61)
		{
			x=(tailleX-1);
			setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::BORD, Piece::orient::OUEST));
			y++;
		}
		else if(count == 61)
		{
			y--;
			x--;
			setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::NORMAL, Piece::orient::NORD));
		}
		else
		{
			if(x == 1)
			{
				y--;
				x=(tailleX-2);
				setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::NORMAL, Piece::orient::NORD));

			}
			else
			{
				x--;
				setPiece(x,y, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::NORMAL, Piece::orient::NORD));
			}
		}
		++count;
	}
}

void Plateau::loadSolution(string name)
{
	ifstream file( name );

	// compter le nombre de lignes
	int count = 0;

	string line;
	int y=0;
	int x=0;
	int Pas=0;

	vector<string> results;

	while ( getline( file, line ) )
	{
		results.clear();
		StringExplode(line, ",", &results);

		for(int i=0; i<(tailleX*2);i++)
		{


		}

		setPiece(0,0, new Piece(StringToInt(results[0]), results[1].c_str()[0], results[2].c_str()[0], results[3].c_str()[0], results[4].c_str()[0], Piece::type::ANGLE, Piece::orient::EST));

		
	}
}

void Plateau::ToFile(string fileName)
{
	ofstream file(fileName);
	for (int i = 0 ; i < 16 ; i++)
	{
		for (int j = 0 ; j<16 ; j++)
		{
			file << getPiece(j,i)->ToString();
		}	
		file << endl;
	}
}

void Plateau::ToString()
{
	for(int y=0;y<tailleY;y++)
	{
		for(int x=0;x<tailleX;x++)
		{
			cout << "|" << setw(3) << PlateauDeJeu[x][y]->numero;
		}
		cout << "|" << endl;
	}
}

int Plateau::Check()
{
	int pts = 0;
	Piece* Piece1=0;
	Piece* Piece2=0;

	for(int j=0;j<this->getTailleY();j++)
	{
		for(int i=0;i<this->getTailleX()-1;i++)
		{
			Piece1 = this->getPiece(i,j);
			Piece2 = this->getPiece(i+1,j);

			if(Piece1->est == Piece2->ouest && Piece1->est != 'Z')
			{
				pts++;
				//cout << Piece1->numero << ", " << Piece1->GetOrientation() << ", " << Piece1->est << " et " << Piece2->numero<< ", " << Piece2->GetOrientation() << ", " << Piece2->ouest << endl;
			}
		}
	}
	for(int i=0;i<this->getTailleX();i++)
	{
		for(int j=0;j<this->getTailleY()-1;j++)
		{
			Piece1 = this->getPiece(i,j);
			Piece2 = this->getPiece(i,j+1);

			if(Piece1->sud == Piece2->nord && Piece1->sud != 'Z')
			{
				pts++;
				//cout << Piece1->numero << ", " << Piece1->GetOrientation() << ", " << Piece1->sud << " et " << Piece2->numero<< ", " << Piece2->GetOrientation() << ", " << Piece2->nord << endl;
			}
		}
	}

	return pts;
}

void Plateau::ChargerPlateau(Plateau* Source)
{
	for(int y=0;y<tailleY;y++)
	{
		for(int x=0;x<tailleX;x++)
		{
			PlateauDeJeu[x][y]->ChargerPiece(Source->getPiece(x,y));
		}
	}	
}